//@ts-nocheck
import { ValidateRule, ValidateError } from '@/types/utils/validate';

import {
  FileUploaderProps,
  TextInputProps,
  ImageSelectorProps,
  DatePickerProps,
  GoodsSelectorProps,
  TagSelectorProps,
  LinkEditorProps,
  SwitchProps,
  PageSelectorProps,
} from '@/cross/components/Form/FormWidget';

import { AutoArrayFormProp } from '@/cross/components/Form/AutoForm';
import { AutoFormProp } from '@/cross/components/Form/type';
import { ViewProp } from '@/cross/components/View.PropType';

export interface FormItemProp {
  label?: string | React.ReactNode;
  field?: string;
  fill?: boolean;
  required?: boolean;
  help?: string | React.ReactNode;
  /** 错误信息 */
  error?: string | React.ReactNode;
  theme?: 'light' | 'dark';
  pattern?: 'v' | 'h';
  labelWidth?: number;
  widgetAlign?: 'left' | 'right';
  widgetContainerStyle?: React.CSSProperties;
  /* 是否显示底线 */
  bottomBorder?: boolean;
  /** Rn 只能使用mtui class */
  className?: string;
  /** Rn 只能使用mtui class */
  fieldClassName?: string;
  /** 错误信息 */
  left?: string | React.ReactNode;
  right?: string | React.ReactNode;
  children?: React.ReactNode;
}

type FormValueType =
  | 'number'
  | 'string'
  | 'boolean'
  | 'object'
  | 'array-object'
  | 'array-number'
  | 'array-string';

type FormItemType =
  | 'select'
  | 'radio'
  | 'file-selector'
  | 'page-selector'
  | 'number-slider'
  | 'color-picker'
  | 'switch'
  | 'smart-image-editor'
  | 'rich-text'
  | 'auto-form'
  | 'auto-array-form'
  | 'item-rows'
  | 'node'
  | 'custom';

export interface FormSelectOption {
  value: number | string;
  label: string;
}

export interface AutoFormChildItem<T> {
  display?: (values: T, parentValue?: any) => boolean;
  /**
   * Cross View Props
   */
  viewProps?: any;
  params?: AutoFormFieldParams<T>;
}

export interface AutoFormFieldParamsBase<T> {
  field?: keyof T;
  label?: React.ReactNode | ((values: T, parentValue?: any) => React.ReactNode);
  labelProps?: FormItemProp;
  type?: FormValueType;
  value?: string | number | boolean | Array<object> | object;
  /** 默认值 */
  default?: string | number | boolean | Array<object> | object;
  f_options?: ((values: T) => Promise<FormSelectOption[]>) | FormSelectOption[];
  asyncParams?: (field: AutoFormFieldParams<T>) => Promise<AutoFormFieldParams<T>>;
  f_default?: string | number;
  help?: string | React.ReactNode;
  display?: (values: T, parentValue?: any) => boolean;
  widgetProps?: {};
  /**
   * 自定义item内容
   */
  render?: (
    field: keyof T,
    value: T[keyof T],
    values: T,
    onChange: (field?: any, value?: any) => void,
  ) => React.ReactNode;
  /**
   * React 元素 当widget为node 时使用->用来显示
   */
  node?: React.ReactNode;
  /**
   * 二级对象
   */
  form?: AutoFormParams<any>;
  formStyle?: object;
  /**
   * item-rows 使用
   * 一个FormItem多个Item并排
   */
  childs?: AutoFormChildItem<T>[];
}

interface AutoFormFieldParamsFileUploader<T> extends AutoFormFieldParamsBase<T> {
  widget: 'file-uploader';
  widgetProps?: FileUploaderProps | ((value: T) => FileUploaderProps);
}

interface AutoFormFieldParamsItemRows<T> extends AutoFormFieldParamsBase<T> {
  widget: 'item-rows';
  widgetProps?: ViewProp | ((value: T) => ViewProp);
}

interface AutoFormFieldParamsTextInput<T> extends AutoFormFieldParamsBase<T> {
  widget: 'text';
  widgetProps?: TextInputProps | ((value: T) => TextInputProps);
}

interface AutoFormFieldParamsSwitch<T> extends AutoFormFieldParamsBase<T> {
  widget: 'switch';
  widgetProps?: SwitchProps | ((value: T) => SwitchProps);
}

interface AutoFormFieldParamsImageSelector<T> extends AutoFormFieldParamsBase<T> {
  widget: 'image-selector';
  widgetProps?: ImageSelectorProps | ((value: T) => ImageSelectorProps);
}

interface AutoFormFieldParamsDatePicker<T> extends AutoFormFieldParamsBase<T> {
  widget: 'date-picker';
  widgetProps?: DatePickerProps | ((value: T) => DatePickerProps);
}

interface AutoFormFieldParamsLinkEditor<T> extends AutoFormFieldParamsBase<T> {
  widget: 'link-editor';
  widgetProps?: LinkEditorProps | ((value: T) => LinkEditorProps);
}

interface AutoFormFieldParamsGoodsSelector<T> extends AutoFormFieldParamsBase<T> {
  widget: 'goods-selector' | 'goods-selector-multiple';
  widgetProps?: GoodsSelectorProps | ((value: T) => GoodsSelectorProps);
}

interface AutoFormFieldParamsTagSelector<T> extends AutoFormFieldParamsBase<T> {
  widget: 'tag-selector' | 'tag-selector-multiple';
  widgetProps?: TagSelectorProps | ((value: T) => TagSelectorProps);
}

interface AutoFormFieldParamsPageSelector<T> extends AutoFormFieldParamsBase<T> {
  widget: 'page-selector';
  widgetProps?: PageSelectorProps | ((value: T) => PageSelectorProps);
}

interface AutoFormFieldParamsAutoArrayForm<T> extends AutoFormFieldParamsBase<T> {
  widget: 'auto-array-form';
  widgetProps?: AutoArrayFormProp | ((value: T) => AutoArrayFormProp);
}

interface AutoFormFieldParamsAutoForm<T> extends AutoFormFieldParamsBase<T> {
  widget: 'auto-form';
  widgetProps?: AutoFormProp<T> | ((value: T) => AutoFormProp<T>);
}

interface AutoFormFieldParamsNode<T> extends AutoFormFieldParamsBase<T> {
  widget: 'node';
}

interface AutoFormFieldParamsOther<T> extends AutoFormFieldParamsBase<T> {
  widget:
    | 'custom'
    | 'select'
    | 'radio'
    | 'rich-text'
    | 'color-picker'
    | 'number-slider'
    | 'smart-image-editor';
  widgetProps?: any;
}

export type AutoFormFieldParams<T> =
  | AutoFormFieldParamsFileUploader<T>
  | AutoFormFieldParamsTextInput<T>
  | AutoFormFieldParamsOther<T>
  | AutoFormFieldParamsImageSelector<T>
  | AutoFormFieldParamsDatePicker<T>
  | AutoFormFieldParamsGoodsSelector<T>
  | AutoFormFieldParamsTagSelector<T>
  | AutoFormFieldParamsLinkEditor<T>
  | AutoFormFieldParamsPageSelector<T>
  | AutoFormFieldParamsAutoArrayForm<T>
  | AutoFormFieldParamsSwitch<T>
  | AutoFormFieldParamsItemRows<T>
  | AutoFormFieldParamsAutoForm<T>
  | AutoFormFieldParamsNode<T>;

export interface IObject {
  [propName: string]: any;
}

export interface AutoFormParams<T extends IObject> extends FormStoreConfig<T> {
  fields?: AutoFormFieldParams<T>[];
}

export interface FormStoreConfig<T extends IObject> {
  /**
   * AutoArrayForm 时使用，为新增项目的默认值
   */
  defaultValue?: T;
  /**
   * 不使用onChange触发校验的字段
   */
  triggerOnBlurFields?: Array<keyof T>;
  /**
   * 对数据编辑是进行操作
   * 返回的对象将会被合并到表单数据中，如修改省的时候,额外修改市区
   */
  before?: (values: T) => object;
  /**
   * 校验规则
   */
  rule?: ValidateRule<T>;
  /**
   * 监听数据变化 如果返回数据可以合并到原数据中 会覆盖原有的值
   * (value, source, prevValue) => object | 不返回值
   */
  watch?: FormStoreWatch<T>;
}

type IValueLessKey<T> = {
  [propName in keyof T]: T[keyof T];
};

export type FormStoreWatch<T extends IObject> = {
  [propName in keyof T]?: (
    value: T[keyof T],
    values: T,
    prevValue: T[keyof T],
  ) => [IValueLessKey<T>] | [IValueLessKey<T>, IValueLessKey<T>] | void;
};

export interface FormResultResultKv {
  [propName: string]: boolean;
  [propName: number]: boolean;
}

export interface FormStatus {
  hideIndex: FormResultResultKv;
  hideField: FormResultResultKv;
  disableIndex: FormResultResultKv;
  disableField: FormResultResultKv;
  errorIndex: FormResultResultKv;
  errorField: ValidateError['fields'];
}
